#include "cpu/exec/template-start.h"

#define instr jmp

static void do_execute() {
	cpu.eip += op_src->val;
	print_asm(str(instr) " %x", cpu.eip + 1 + DATA_BYTE);
}

make_instr_helper(si)
#if DATA_BYTE == 4
make_helper(jmp_rm_l) {
	int len = decode_rm_l(eip + 1);
	cpu.eip = op_src->val - (len + 1);
	print_asm(str(instr) " *%s", op_src->str);
	return len + 1;
}

make_helper(ljmp) {
	uint32_t data0;
	uint16_t data1;
	data0 = instr_fetch(cpu.eip + 1, 4);
	data1 = instr_fetch(cpu.eip + 5, 2);

	uint16_t index;
	Segment_Descriptor sreg_tmp;
	cpu.cs.selector = data1;
	index = (cpu.cs.selector >> 3);

	Assert((index << 3) <= cpu.gdtr.limit, "Index is out of limit!");

	lnaddr_t addr_tmp = cpu.gdtr.base + (index << 3);
	sreg_tmp.part0 = lnaddr_read(addr_tmp, 4);
	sreg_tmp.part1 = lnaddr_read(addr_tmp + 4, 4);

	uint32_t base;
	base = sreg_tmp.base0;
	base += sreg_tmp.base1 << 16;
	base += sreg_tmp.base2 << 24;

	cpu.cs.base = base;

	uint32_t limit;
	limit = sreg_tmp.limit0;
	limit += sreg_tmp.limit1 << 16;
	limit += 0xfff << 20;

	cpu.cs.limit = limit;

	cpu.eip = data0 - 7;

	return 7;
}

#endif
#include "cpu/exec/template-end.h"
